package com.fzy.common.file.pdf;

import com.fzy.common.file.pdf.component.IHeaderFooter;
import com.fzy.common.file.pdf.component.PDFBuilder;
import com.fzy.common.template.FreemarkerUtil;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

public class PDFUtil {
    //PDF页眉、页脚定制工具
    private IHeaderFooter headerFooterBuilder;
    private String saveFilePath;

    /**
     * @param fileName 输出PDF文件名
     * @param data     模板所需要的数据
     * @description 导出pdf到文件
     */
    public String exportToFile(String fileName, Object data) throws Exception {

        String htmlData = FreemarkerUtil.getContent(fileName, data);
        if (StringUtils.isEmpty(saveFilePath)) {
            saveFilePath = getDefaultSavePath(fileName);
        }
        File file = new File(saveFilePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        FileOutputStream outputStream = null;
        try {
            //设置输出路径
            outputStream = new FileOutputStream(saveFilePath);
            //设置文档大小
            Document document = new Document(PageSize.A4);
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);

            //设置页脚
            PDFBuilder builder = new PDFBuilder(headerFooterBuilder, data);
            builder.setPresentFontSize(10);
            writer.setPageEvent(builder);

            //输出为PDF文件
            convertToPDF(writer, document, htmlData);
        } catch (Exception ex) {
            throw new Exception("PDF export to File fail", ex);
        } finally {
            IOUtils.closeQuietly(outputStream);
        }
        return saveFilePath;

    }

    /**
     * 生成PDF到输出流中（ServletOutputStream用于下载PDF）
     *
     * @param ftlPath  ftl模板文件的路径（不含文件名）
     * @param data     输入到FTL中的数据
     * @param response HttpServletResponse
     * @return
     * @throws Exception
     */
    public OutputStream exportToResponse(String ftlPath, Object data, HttpServletResponse response) throws Exception {

        String html = FreemarkerUtil.getContent(ftlPath, data);

        try {
            OutputStream out = null;
            out = response.getOutputStream();
            //设置文档大小
            Document document = new Document(PageSize.A4);
            PdfWriter writer = PdfWriter.getInstance(document, out);
            //设置页眉页脚
            PDFBuilder builder = new PDFBuilder(headerFooterBuilder, data);
            writer.setPageEvent(builder);
            //输出为PDF文件
            convertToPDF(writer, document, html);
            return out;
        } catch (Exception ex) {
            throw new Exception("PDF export to response fail", ex);
        }

    }

    /**
     * @description PDF文件生成
     */
    private void convertToPDF(PdfWriter writer, Document document, String htmlString) throws Exception {
        document.open();
        try {
            XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(htmlString.getBytes()));
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("PDF文件生成异常", e);
        } finally {
            document.close();
        }

    }

    /**
     * @description 创建默认保存路径
     */
    private String getDefaultSavePath(String fileName) {
        String classpath = PDFUtil.class.getClassLoader().getResource("").getPath();
        String saveFilePath = classpath + "pdf/" + fileName;
        File f = new File(saveFilePath);
        if (!f.getParentFile().exists()) {
            f.mkdirs();
        }
        return saveFilePath;
    }

    /**
     * @description 获取字体设置路径
     */
    public static String getFontPath() {
        String classpath = PDFUtil.class.getClassLoader().getResource("").getPath();
        return classpath + "fonts";
    }

    public IHeaderFooter getHeaderFooterBuilder() {
        return headerFooterBuilder;
    }

    public void setHeaderFooterBuilder(IHeaderFooter headerFooterBuilder) {
        this.headerFooterBuilder = headerFooterBuilder;
    }

    public String getSaveFilePath() {
        return saveFilePath;
    }

    public void setSaveFilePath(String saveFilePath) {
        this.saveFilePath = saveFilePath;
    }

}